package com.yhq.yhqproject.base.modules.base.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yhq.yhqproject.base.common.utils.IdGen;
import com.yhq.yhqproject.base.common.utils.RedisUtil;
import com.yhq.yhqproject.base.modules.base.entity.BaseResult;
import com.yhq.yhqproject.base.modules.base.repo.BaseResultRepo;
import com.yhq.yhqproject.base.modules.board.entity.AiTemplate;
import com.yhq.yhqproject.base.modules.board.entity.TemplateHistory;
import com.yhq.yhqproject.base.modules.board.repo.TemplateHistoryRepo;
import com.yhq.yhqproject.base.modules.board.service.AiTemplateService;
import com.yhq.yhqproject.base.modules.chat.service.ChatGPTService;
import com.yhq.yhqproject.base.modules.chat.service.LbChatService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

public abstract class BaseParseResultService {
    @Resource
    private LbChatService lbChatService;
    @Resource
    private ChatGPTService chatGPTService;
    @Resource
    private AiTemplateService aiTemplateService;
    @Resource
    private BaseResultRepo repo;
    @Resource
    private TemplateHistoryRepo historyRepo;
    @Value("${serve.choice}")
    protected String aiChoice;
    @Resource
    private RedisUtil redisUtil;

    public String laiBoChatResult(String uri, JSONObject param, boolean isJson) {
        JSONObject json = new JSONObject();
        json.put("json_type", isJson);
        JSONArray data = new JSONArray();
        data.add(param);
        json.put("data", data);
        //处理数据库换成和请求AI业务
        String md5 = DigestUtil.md5Hex(json.toJSONString());
        BaseResult result = repo.findBaseResultByMd5(md5);
        if (result == null) {
            return LaiBoChatReq(md5, uri, json);
        } else {
            if (result.getData() == null || result.getData().length() == 0) {
                repo.deleteByMd5(md5);
                return LaiBoChatReq(md5, uri, json);
            }
            return result.getData();
        }
    }

    public String getChatGPTResult(String title, List<String> params, Integer up) {
        AiTemplate m = aiTemplateService.queryByTitle(title);
        if (m == null || m.getContent() == null || m.getContent().length() == 0) {
            throw new RuntimeException(title + "模板不存在请检查数据库");
        }
        String prompt = String.format(m.getContent(), params.toArray());
        String md5 = DigestUtil.md5Hex(prompt);
        BaseResult result = repo.findBaseResultByMd5(md5);
        if (result == null) {
            return chatGPTReq(title, params, md5, prompt);
        } else {
            if (result.getData() == null || result.getData().length() == 0 || up == 1) {
                repo.deleteByMd5(md5);
                return chatGPTReq(title, params, md5, prompt);
            }
            return result.getData();
        }
    }

    /**
     * 存储请求历史
     *
     * @param uri
     * @param json
     * @return
     */
    private String LaiBoChatReq(String md5, String uri, JSONObject json) {
        String key = "ai:ts:" + md5;
        if (redisUtil.tryLock(key)) {
            String id = saveBaseResult(uri, Collections.singletonList(json.toJSONString()), md5, "LaiBo API No Prompt");
            String data = lbChatService.requestLbChatForResult(uri, json);
            updateBaseResult(id, data);
            redisUtil.releaseLock(key);
            return data;
        }
        throw new RuntimeException("Mul " + md5 + " Update");
    }

    private String chatGPTReq(String title, List<String> params, String md5, String prompt) {
        String key = "ai:ts:" + md5;
        if (redisUtil.tryLock(key)) {
            String id = saveBaseResult(title, params, md5, prompt);
            String data = chatGPTService.requestChatForResult(prompt);
            updateBaseResult(id, data);
            redisUtil.releaseLock(key);
            return data;
        }
        throw new RuntimeException("Mul " + md5 + " Update");

    }

    private String saveBaseResult(String title, List<String> params, String md5, String prompt) {
        BaseResult s = new BaseResult();

        s.setId(IdGen.get().nextSid());
        s.setMd5(md5);
        s.setTitle(title);
        s.setParams(params);
        s.setPrompt(prompt);
        s.setData("");
        s.setCreateTime(System.currentTimeMillis());
        repo.add(s);
        //history
        TemplateHistory h = new TemplateHistory();
        BeanUtils.copyProperties(s, h);
        historyRepo.add(h);
        return s.getId();
    }

    private void updateBaseResult(String id, String data) {
        BaseResult s = new BaseResult();
        s.setId(id);
        s.setData(data);
        s.setUpdateTime(System.currentTimeMillis());
        repo.update(s);
        //history
        TemplateHistory h = new TemplateHistory();
        BeanUtils.copyProperties(s, h);
        historyRepo.update(h);
    }


}
